package com.bkgy.modularbx.slip.utils;

import org.apache.commons.math3.stat.descriptive.moment.Variance;
import org.apache.commons.math3.stat.regression.SimpleRegression;

/**
 * 数学工具类，提供各种数学计算方法。
 * 主要用于处理轧机数据分析中的数学计算，包括方差、斜率、最大值、平均值等统计指标的计算。
 *
 * @author Trae
 * @version 1.0
 */
public class MathUtils {

    /**
     * 计算数据序列的方差。
     * 
     * @param data 输入的float类型数组
     * @return 返回数据序列的方差值
     */
    public static double calculateVariance(float[] data) {
        Variance variance = new Variance();
        return variance.evaluate(convertToDouble(data));
    }

    /**
     * 通过线性回归计算两个数据序列的斜率。
     * 
     * @param x x轴数据序列
     * @param y y轴数据序列
     * @return 返回线性回归后的斜率，如果输入数据无效则返回0.0
     */
    public static double calculateSlope(float[] x, float[] y) {
        if (x.length != y.length || x.length == 0) {
            return 0.0;
        }

        SimpleRegression regression = new SimpleRegression();
        for (int i = 0; i < x.length; i++) {
            regression.addData(x[i], y[i]);
        }

        return regression.getSlope();
    }

    /**
     * 查找数组中的最大值。
     * 
     * @param data 输入的float类型数组
     * @return 返回数组中的最大值
     */
    public static float findMax(float[] data) {
        float max = Float.MIN_VALUE;
        for (float value : data) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }

    /**
     * 计算数组的算术平均值。
     * 
     * @param data 输入的float类型数组
     * @return 返回数组的平均值，如果数组为空则返回0
     */
    public static float calculateMean(float[] data) {
        float sum = 0;
        for (float value : data) {
            sum += value;
        }
        return data.length > 0 ? sum / data.length : 0;
    }

    /**
     * 计算数据序列中的下降趋势比例。
     * 通过比较相邻数据点来统计下降的比例。
     * 
     * @param data 输入的float类型数组
     * @return 返回下降趋势的比例（0-1之间的值），如果数据点不足则返回0
     */
    public static float calculateDownwardTrend(float[] data) {
        if (data.length <= 1) {
            return 0;
        }

        int downCount = 0;
        int totalCount = 0;

        for (int i = 1; i < data.length; i++) {
            if (data[i] - data[i-1] != 0) {
                totalCount++;
                if (data[i] - data[i-1] < 0) {
                    downCount++;
                }
            }
        }

        return totalCount > 0 ? (float) downCount / totalCount : 0;
    }

    /**
     * 计算数据序列中超过指定阈值的比例。
     * 
     * @param data 输入的float类型数组
     * @param threshold 阈值
     * @return 返回超过阈值的数据点比例（0-1之间的值），如果数组为空则返回0
     */
    public static float calculateThresholdExceedRatio(float[] data, float threshold) {
        int exceedCount = 0;
        for (float value : data) {
            if (Math.abs(value) > threshold) {
                exceedCount++;
            }
        }
        return data.length > 0 ? (float) exceedCount / data.length : 0;
    }

    /**
     * 将float类型数组转换为double类型数组。
     * 
     * @param input 输入的float类型数组
     * @return 转换后的double类型数组
     */
    private static double[] convertToDouble(float[] input) {
        double[] output = new double[input.length];
        for (int i = 0; i < input.length; i++) {
            output[i] = input[i];
        }
        return output;
    }
}